<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>菜单树编辑</title>
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600;700;800&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="/css/bootstrap.css">
    <link rel="stylesheet" href="/vendors/iconly/bold.css">
    <link rel="stylesheet" href="/vendors/perfect-scrollbar/perfect-scrollbar.css">
    <link rel="stylesheet" href="/vendors/bootstrap-icons/bootstrap-icons.css">
    <link rel="stylesheet" href="/css/app.css">
    <link rel="stylesheet" href="/css/antd-layout.css">
    <script src="/js/common.js"></script>
    <script src="/js/jquery.3.6.0.min.js"></script>
    <script src='/js/vue.2.6.4.min.js'></script>

    <style>
        /* Ant Design 风格树形菜单 */
        .tree-menu {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            user-select: none;
            background: #ffffff;
            border-radius: 2px;
        }

        .node-item {
            position: relative;
            transition: all 0.2s;
        }

        .node-content {
            display: flex;
            align-items: center;
            padding: 6px 12px;
            border-radius: 2px;
            transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
            margin: 2px 0;
        }

        .node-content:hover {
            background: #f5f5f5;
        }

        .node-icon {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 20px;
            height: 20px;
            margin-right: 8px;
            color: #1890ff;
            font-size: 16px;
            transition: color 0.3s;
        }

        .node-icon.folder {
            color: #faad14;
        }

        .node-icon.file {
            color: #8c8c8c;
        }

        .node-label {
            flex: 1;
            font-size: 14px;
            color: rgba(0, 0, 0, 0.85);
            line-height: 22px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .node-actions {
            display: flex;
            align-items: center;
            gap: 6px;
            margin-left: auto;
        }

        .tree-btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            height: 28px;
            padding: 0 12px;
            font-size: 13px;
            border-radius: 4px;
            border: 1px solid;
            background: #ffffff !important;
            color: rgba(0, 0, 0, 0.65);
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
            white-space: nowrap;
        }

        .tree-btn:hover {
            color: #40a9ff;
            border-color: #40a9ff;
            background: #ffffff !important;
        }

        .tree-btn:active {
            color: #096dd9;
            border-color: #096dd9;
            background: #ffffff !important;
        }

        .tree-btn:focus {
            background: #ffffff !important;
            outline: none;
            box-shadow: none;
        }

        .tree-btn.btn-add {
            color: #67c23a;
            border-color: #c2e7b0;
            background: #f0f9ff !important;
        }

        .tree-btn.btn-add:hover {
            color: #85ce61;
            border-color: #67c23a;
            background: #e1f3d8 !important;
        }

        .tree-btn.btn-primary {
            color: #409eff;
            border-color: #c6e2ff;
            background: #ecf5ff !important;
        }

        .tree-btn.btn-primary:hover {
            color: #66b1ff;
            border-color: #409eff;
            background: #d9ecff !important;
        }

        .tree-btn.btn-danger {
            color: #f56c6c;
            border-color: #fbc4c4;
            background: #fef0f0 !important;
        }

        .tree-btn.btn-danger:hover {
            color: #f78989;
            border-color: #f56c6c;
            background: #fde2e2 !important;
        }

        .tree-btn.btn-link {
            color: #909399;
            border-color: #dcdfe6;
            background: #f4f4f5 !important;
        }

        .tree-btn.btn-link:hover {
            color: #606266;
            border-color: #909399;
            background: #e9e9eb !important;
        }

        .children-list {
            padding-left: 24px;
            margin-left: 12px;
            border-left: 1px dashed #d9d9d9;
            overflow: hidden;
            transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        }

        .node-indent {
            display: inline-block;
            width: 24px;
        }

        /* 图标样式 */
        .bi-folder-fill::before {
            color: #faad14;
        }

        .bi-folder::before {
            color: #faad14;
        }

        .bi-file-earmark::before {
            color: #8c8c8c;
        }

        .btn-circle {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            padding: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    </style>
    <script src="../../static/js/jquery.3.6.0.min.js"></script>
</head>
<body>
<div id="app">
    <div id="nav-bar-container"></div>

    <div id="main">
        <header class="mb-3">
            <a href="#" class="burger-btn d-block d-xl-none">
                <i class="bi bi-justify fs-3"></i>
            </a>
        </header>

        <div class="page-heading">
            <section class="section">
                <div class="row">
                    <div class="col-12 col-md-12">
                        <div class="card">
                            <div class="card-header d-flex justify-content-between align-items-center">
                                <h5 class="mb-0">菜单管理</h5>
                                <a href="#" class="btn btn-primary" data-bs-toggle="modal"
                                   data-bs-target="#inlineForm" @click="beginAdd(0)">
                                    <i class="bi bi-plus-lg me-1"></i>新增
                                </a>
                            </div>
                            <div class="card-body">
                                <div class="row">
                                    <div class="col-md-11">
                                        <div class="row">
                                            <div class="col-md-2">

                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <!-- Table with outer spacing -->
                                <div class="table-responsive">
                                    <!--                                    <div id="tree-container"></div>-->
                                    <tree-menu :tree-data="treeData"></tree-menu>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </section>
        </div>

        <!--        弹窗-->
        <div class="modal fade text-left" id="inlineForm" tabindex="-1" role="dialog"
             aria-labelledby="myModalLabel33" aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable"
                 role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title" id="myModalLabel33">编辑 </h4>
                        <button type="button" class="close" data-bs-dismiss="modal"
                                aria-label="Close">
                            <i data-feather="x"></i>
                        </button>
                    </div>
                    <orm action="#">
                        <div class="modal-body">
                            <div class="form-group">
                                <div class="row">
                                    <div class="col-3">
                                        名称:
                                    </div>
                                    <div class="col-9">
                                        <input type="text" placeholder="类别名称"
                                               class="form-control" v-model="menuModel.name">
                                    </div>
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="row">
                                    <div class="col-3">
                                        排序值:
                                    </div>
                                    <div class="col-9">
                                        <input type="number" placeholder="排序值"
                                               class="form-control" v-model="menuModel.sortNum">
                                    </div>
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="row">
                                    <div class="col-3">
                                        类型:
                                    </div>
                                    <div class="col-9">
                                        <select class="form-control" v-model="menuModel.menuType">
                                            <option value="1">菜单</option>
                                            <option value="2">文件</option>
                                        </select>
                                    </div>
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="row">
                                    <div class="col-3">
                                        父ID:
                                    </div>
                                    <div class="col-9">
                                        <input type="number" placeholder="排序值"
                                               class="form-control" v-model="menuModel.parentId">
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-light-secondary"
                                    data-bs-dismiss="modal">
                                <i class="bx bx-x d-block d-sm-none"></i>
                                <span class="d-none d-sm-block">关闭</span>
                            </button>
                            <button type="button" class="btn btn-primary ml-1"
                                    data-bs-dismiss="modal">
                                <i class="bx bx-check d-block d-sm-none"></i>
                                <span class="d-none d-sm-block" @click="submitItem()">提交</span>
                            </button>
                        </div>
                    </orm>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="/vendors/perfect-scrollbar/perfect-scrollbar.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
<script src="/js/nav-bar.js"></script>
<script src="/js/main.js"></script>
</body>

</html>
<script type="text/javascript">

    var mainVue;

    // 树形菜单组件
    const TreeItem = {
        name: 'TreeItem', // 必须命名才能递归
        template: `
          <div class="node-item">
            <div class="node-content" :style="{ paddingLeft: depth * 24 + 'px' }">
              <i :class="[
                'bi',
                'node-icon',
                node.menuType === 1 
                  ? (isExpanded ? 'bi-folder-fill' : 'bi-folder') 
                  : 'bi-file-earmark',
                node.menuType === 1 ? 'folder' : 'file'
              ]"></i>
              <span class="node-label">
                <span style="color: #8c8c8c; font-size: 12px;">ID:{{ node.id }}</span>
                <span style="margin: 0 6px;">|</span>
                <span>{{ node.name }}</span>
              </span>
              <div class="node-actions">
                <button v-if="node.menuType === 1" 
                        @click="beginAdd(node.id)" 
                        data-bs-toggle="modal"
                        data-bs-target="#inlineForm"
                        class="tree-btn btn-add">
                  添加
                </button>
                <button @click="beginEdit(node)" 
                        data-bs-toggle="modal"
                        data-bs-target="#inlineForm"
                        class="tree-btn btn-primary">
                  编辑
                </button>
                <button @click="beginDel(node.id)"
                        class="tree-btn btn-danger">
                  删除
                </button>
                <button @click="goQuestionPage(node.id)"
                        class="tree-btn btn-link">
                  跳转
                </button>
              </div>
            </div>
            <div class="children-list" v-if="node.children && isExpanded">
              <tree-item
                  v-for="child in node.children"
                  :key="child.id"
                  :node="child"
                  :depth="depth + 1"
              />
            </div>
          </div>
        `,
        props: {
            node: {type: Object, required: true},
            depth: {type: Number, default: 0}
        },
        data() {
            return {
                isExpanded: true // 默认展开所有
            }
        },
        methods: {
            'beginAdd': function (parentId) {
                mainVue.menuModel = {
                    id: 0,
                    name: '',
                    sortNum: 0,
                    parentId: parentId,
                    menuType: 1,
                    examBankId: this.examBankId
                }
            },
            'beginEdit':function (){
               mainVue.menuModel = {
                   id: this.node.id,
                   name: this.node.name,
                   sortNum: this.node.sortNum,
                   parentId: this.node.parentId,
                   menuType: this.node.menuType,
                   examBankId: this.examBankId
               }
            },
            'beginDel': function (id) {
                if (confirm("确定删除吗？")) {
                    $.ajax({
                        type: 'post',
                        contentType: "application/json",
                        dataType: "json",
                        url: '/common/deleteCardMenu',
                        data: JSON.stringify({id: id}),
                        beforeSend: function (xhr) {
                            xhr.setRequestHeader("X-EM-Token", mainVue.userInfo.token);
                        },
                        cache: false
                    }).done(function (data) {
                        if (data.success) {
                            mainVue.getMenu()
                        } else {
                            alert(data.errMessage);
                            if (data.timeOut) {
                                window.location.href = "/view/userLogin";
                            }
                        }
                    });
                }
            },'goQuestionPage':function (id){
                window.open("/view/question?menuId="+id, "_blank");
            }
        }
    }

    // 树形菜单容器组件
    const TreeMenu = {
        template: `
          <div class="tree-menu">
            <tree-item
                v-for="node in treeData"
                :key="node.id"
                :node="node"
                :depth="0"
            />
          </div>
        `,
        components: {TreeItem},
        props: ['treeData']
    }

    // 示例数据
    const treeData = [
        {
            "examBankId": 101,
            "id": 0,
            "menuType": 1,
            "name": "菜单0",
            "parentId": 0
        },
        {

            "examBankId": 101,
            "id": 2,
            "menuType": 1,
            "name": "菜单2",
            "parentId": 0
        }
    ];

    // 自动挂载逻辑
    document.addEventListener('DOMContentLoaded', () => {
        mainVue = new Vue({
            el: '#main',
            components: {TreeMenu},
            // template: '<TreeMenu :tree-data="treeData"/>',
            data: {
                treeData,
                examBankId: 101,
                userInfo: {userName: '', token: '', imageHeadUrl: ''},
                menuModel: {
                    id: 0,
                    name: '',
                    sortNum: 0,
                    parentId: 0,
                    menuType: 1,
                    examBankId: this.examBankId
                }
            },
            methods: {
                'beginAdd': function (parentId) {
                    this.menuModel = {
                        id: 0,
                        name: '',
                        sortNum: 0,
                        parentId: parentId,
                        menuType: 1,
                    }
                },
                'init': function () {
                    var examBankId = localStorage.getItem("examBankId");
                    if (examBankId) {
                        this.examBankId = examBankId;
                    }
                    var thisVue = this;
                    var localUserInfo = localStorage.getItem("userInfo");
                    if (localUserInfo) {
                        thisVue.$set(thisVue, 'userInfo', JSON.parse(localUserInfo));
                    }
                    thisVue.getMenu();
                },
                'getMenu': function () {
                    var thisVue = this;
                    $.ajax({
                        type: 'post',
                        contentType: "application/json",
                        dataType: "json",
                        url: '/common/getCardMenu',
                        data: JSON.stringify({id: thisVue.examBankId}),
                        beforeSend: function (xhr) {
                            xhr.setRequestHeader("X-EM-Token", thisVue.userInfo.token);
                        },
                        cache: false
                    }).done(function (data) {
                        if (data.success) {
                            thisVue.treeData = data.data;
                        } else {
                            alert(data.errMessage);
                            if (data.timeOut) {
                                window.location.href = "/view/userLogin";
                            }
                        }
                    });
                },
                'submitItem': function () {
                    var thisVue = this;
                    thisVue.menuModel.examBankId = thisVue.examBankId;
                    var url = '/common/addCardMenu';
                    if (thisVue.menuModel.id>0) {
                        url = '/common/updateCardMenu';
                    }
                    $.ajax({
                        type: 'post',
                        contentType: "application/json",
                        dataType: "json",
                        url: url,
                        data: JSON.stringify(thisVue.menuModel),
                        beforeSend: function (xhr) {
                            xhr.setRequestHeader("X-EM-Token", thisVue.userInfo.token);
                        },
                        cache: false
                    }).done(function (data) {
                        if (data.success) {
                            thisVue.getMenu();
                        } else {
                            alert(data.errMessage);
                            if (data.timeOut) {
                                window.location.href = "/view/userLogin";
                            }
                        }
                    });
                }
            }
        });
        mainVue.init();
    })
</script>
